package Servidor;

import PaqueteCORBA.*;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Sesion extends SesionCORBAPOA {

    private AulaVirtual _aulaVirtual;
    private Usuario _usuario;
    private String _nombre;
    protected Comunicaciones.CorbaConexionServidor _corbaConexionServidor;
    protected ClienteCORBA _clienteCORBA;

    public Sesion(AulaVirtual aulaVirtual, String nombre, Comunicaciones.CorbaConexionServidor corbaCS) {
        _aulaVirtual = aulaVirtual;
        _nombre = nombre;
        _corbaConexionServidor = corbaCS;
        // registrar el sirviente con el nombre de la sesion
        _corbaConexionServidor.registrarSesion(this, _nombre);
        // Cliente sin resolver: debo esperar a que lo registre el cliente
        // con el nombre que le devolvera Mediateca.entrar() que ha llamado
        // a este constructor
        _clienteCORBA = null;
    }

    public void setSistema(AulaVirtual aSi) {
        this._aulaVirtual = aSi;
    }

    @Override
    public void desconectar() {
        _aulaVirtual.deleteSesion(this);
        _usuario.deleteSesion();
    }

    @Override
    public void matricular(String aIdAsignatura) throws PaqueteCORBA.excepcion {

        Asignatura a = _aulaVirtual.findAsignatura(aIdAsignatura);

        if (a != null) {
            _usuario.matricular(a);
        } else {
            throw new PaqueteCORBA.excepcion("No existe la asignatura");
        }
    }

    @Override
    public void anyadirPregunta(String aIdAsig, String aIdTema, String aEnunciadoP) {
        Profesor profesor;

        profesor = (Profesor) _usuario;
        profesor.anyadirPregunta(aIdAsig, aIdTema, aEnunciadoP);
    }

    @Override
    public void anyadirRespuesta(String aIdPregunta, String aEnunciadoR, boolean aEsCierta) throws excepcion {
        Profesor profesor;

        profesor = (Profesor) _usuario;
        try {
            profesor.anyadirRespuesta(aIdPregunta, aEnunciadoR, aEsCierta);
        } catch (Exception ex) {
            throw new excepcion(ex.getMessage());
        }

    }

    @Override
    public void ponerExamen(String aIdAsignatura, PaqueteCORBA.InfoTema[] aTemas, String aFechaIni, String aFechaFin) throws PaqueteCORBA.excepcion {
        Profesor prof = (Profesor) this._usuario;

        SimpleDateFormat formatoDelTexto = new SimpleDateFormat("dd/MM/yyyy");
        Date fechaInicial = null;
        Date fechaFinal = null;
        try {

            fechaInicial = formatoDelTexto.parse(aFechaIni);
            fechaFinal = formatoDelTexto.parse(aFechaFin);
			
			fechaInicial.setYear(fechaInicial.getYear() + 2000);
			fechaFinal.setYear(fechaFinal.getYear() + 2000);

        } catch (ParseException ex) {

            ex.printStackTrace();

        }

        try {
            prof.ponerExamen(aIdAsignatura, aTemas, fechaInicial, fechaFinal);
        } catch (Exception ex) {
            throw new excepcion(ex.getMessage());
        }
    }

	@Override
    public PaqueteCORBA.InfoExamenEspecifico verExamenEspecifico(String aIdExamen) {
		Examen ex = _aulaVirtual.findExamen(aIdExamen);

		ArrayList<ExamenEspecifico> examenesRealizados = _usuario.getExamenesRealizados();

		for(int i = 0; i < examenesRealizados.size(); i++)
			if(ex == examenesRealizados.get(i).getExamen())
				return examenesRealizados.get(i).getExamenCompleto();


		return null;
    }

    @Override
    public PaqueteCORBA.InfoExamen[] verNotasDelExamen(String aIdExamen) {
        Profesor prof = (Profesor) _usuario; //Una de las precondiciones es que el usuario sea un profesor. Por lo que no debe haber error en el cast

        PaqueteCORBA.InfoExamen[] infoExamenes = prof.verNotasDelExamen(aIdExamen);

        return infoExamenes;
    }

    @Override
    public void contestarPregunta(String aIdExamenEsp, String aIdPregunta, String aIdRespuesta) {
        Alumno a = (Alumno) _usuario;
        a.contestarPregunta(aIdExamenEsp, aIdPregunta, aIdRespuesta);
    }

    public Aviso verNotificacion(String aIdNotificacion) {
        return _usuario.verNotificacion(aIdNotificacion);
    }

    /**
     * @param aUser
     * @param aPassword
     * @return -1 Si el usuario no existe o el pass no coincide 0 Si el usuario
     * existe y es profesor 1 Si el usuario existe y es alumno
     */
    @Override
    public int identificarse(String aUser, String aPassword) {
        Usuario user;
        System.out.println("Usu: " + aUser + "  pass: " + aPassword);
        user = _aulaVirtual.identificar(aUser, aPassword);
        int ret = -1;

        if (user == null) {
            ret = -1;
        } else {
            _usuario = user;
            user.setSesion(this);

            if (_usuario instanceof Profesor) {
                ret = 0;
            } else if (_usuario instanceof Alumno) {
                ret = 1;
            }
        }

        return ret;
    }

    @Override
    public InfoExamenEspecifico generarExamen(String aIdExamen) throws excepcion {
        Alumno alu = (Alumno) _usuario;

        try {
            ExamenEspecifico ee = _aulaVirtual.generarExamen(aIdExamen, alu);
            InfoExamenEspecifico iee = ee.getExamenCompleto();

            return iee;
        } catch (Exception e) {
            PaqueteCORBA.excepcion ex = new excepcion();
            ex.msg = e.getMessage();

            throw ex;
        }
    }

    @Override
    public InfoAsignatura[] getAsignaturas() throws PaqueteCORBA.excepcion {
        ArrayList<Asignatura> asignaturas = _aulaVirtual.getAsignaturas();
        InfoAsignatura[] retorno = new InfoAsignatura[asignaturas.size()];

        if (asignaturas.size() == 0) {
            throw new PaqueteCORBA.excepcion("El usuario no está matriculado en ninguna asignatura");
        }

        for (int i = 0; i < asignaturas.size(); i++) {
            String nombreAsignatura = asignaturas.get(i).getNombre();

            retorno[i] = new InfoAsignatura();
            retorno[i].idAsignatura = nombreAsignatura;
            retorno[i].matriculado = (_usuario.findAsignatura(nombreAsignatura) != null);
        }

        return retorno;
    }

    @Override
    public String[] getTemasAsignatura(String idAsignatura) throws PaqueteCORBA.excepcion {
        Asignatura asignatura = _aulaVirtual.findAsignatura(idAsignatura);

        if (asignatura != null) {
            ArrayList<Tema> temas = asignatura.getTemas();
            String[] retorno = new String[temas.size()];

            for (int i = 0; i < temas.size(); i++) {
                retorno[i] = temas.get(i).getNombre();
            }

            return retorno;
        } else {
            throw new PaqueteCORBA.excepcion("No existe la asignatura " + idAsignatura + " o el usuario no está matriculado en ella");
        }
    }

    @Override
    public InfoExamen[] getExamenes() throws PaqueteCORBA.excepcion {
        InfoExamen[] ie = null;

        if (_usuario instanceof Alumno) {
            ArrayList<ExamenEspecifico> examenes = _usuario.getExamenesRealizados();
            ie = new InfoExamen[examenes.size()];

            for (int i = 0; i < examenes.size(); i++) {
                ie[i] = new InfoExamen();
                ie[i].idExamen = examenes.get(i).getExamen().getIdExamen();
                ie[i].nombre = examenes.get(i).getExamen().getAsignatura().getNombre() + " " + examenes.get(i).getExamen().getFecha();
                ie[i].nota = examenes.get(i).getNota();
            }

        }
		
		if(_usuario instanceof Profesor){
			Profesor prof = (Profesor) _usuario;
			ArrayList<Examen> examenes = prof.getExamenesProf();
			ie = new InfoExamen[examenes.size()];

			for(int i = 0; i < examenes.size(); i++){
				ie[i] = new InfoExamen();
				ie[i].idExamen = examenes.get(i).getIdExamen();
				ie[i].nombre = "No realizado";
				ie[i].nota = 0;
			}
		}

        if (ie == null) {
            PaqueteCORBA.excepcion ex = new PaqueteCORBA.excepcion();
            ex.msg = "Para ver la nota de los examenes se debe especificar la asignatura.";

            throw ex;
        } else if (ie.length == 0) {
            PaqueteCORBA.excepcion ex = new PaqueteCORBA.excepcion();
            ex.msg = "El alumno no ha realizado ningún examen.";

            throw ex;
        }

        return ie;
    }

    public void enviarAviso(String msg) {
        if (_clienteCORBA == null) {
            String nombreCliente = new String(_nombre + "Cliente");
            _clienteCORBA = _corbaConexionServidor.resolverCliente(nombreCliente);
        }

        _clienteCORBA.avisar(msg);
    }

    public Usuario getUsuario() {
        return _usuario;
    }

    @Override
    public InfoNotificacionExamen[] getNotificacionesExamen() {
        ArrayList<Aviso> avisos = _usuario.getAvisos();
        ArrayList<AvisoInformacion> ai = new ArrayList<AvisoInformacion>();

        for (int i = 0; i < avisos.size(); i++) {
            if (avisos.get(i) instanceof AvisoInformacion) {
                ai.add((AvisoInformacion) avisos.get(i));
            }
        }

        InfoNotificacionExamen[] ine = new InfoNotificacionExamen[ai.size()];
        for (int i = 0; i < ai.size(); i++) {
            ine[i] = new InfoNotificacionExamen();
            ine[i].idNotificacion = ai.get(i).getIdAviso();
            ine[i].fechaFin = ai.get(i).getExamen().getFechaFinal().toString();
            ine[i].fechaIni = ai.get(i).getExamen().getFechaInicial().toString();
            ine[i].idExamen = ai.get(i).getExamen().getIdExamen();
            ine[i].leido = ai.get(i).getLeido();
			ine[i].corregido = ai.get(i).getExamen().getCorreccion();
        }
        return ine;
    }

    @Override
    public void terminarExamen(String idExamen, InfoExamenEspecifico iee) {      
        if (_usuario instanceof Alumno) {
            Alumno a = (Alumno) _usuario;
            
            for (int i = 0; i < iee.preguntas.length; i++) {
                for (int j = 0; j < iee.preguntas[i].respuestas.length; j++)
                    if (iee.preguntas[i].respuestas[j].marcada)
                        a.contestarPregunta(idExamen, iee.preguntas[i].enunciadoPregunta, iee.preguntas[i].respuestas[j].respuesta);
            }
			
			a.terminarExamen(idExamen);
        }
    }

    @Override
    public InfoExamenEspecifico verExamenEspecificoAlumno(String idExamen, String idAlumno) {
        Alumno a = (Alumno) _aulaVirtual.findUser(idAlumno);
		
		ArrayList<ExamenEspecifico> examenesRealizados = a.getExamenesRealizados();

		for(int i = 0; i < examenesRealizados.size(); i++)
			if(idExamen.equals(examenesRealizados.get(i).getExamen().getIdExamen()))
				return examenesRealizados.get(i).getExamenCompleto();


		return null;
    }

    @Override
    public void setNoficacionLeida(String idAviso) {
        _usuario.verNotificacion(idAviso);
    }
}
